// (C) Copyright 2010 Communications Programming, Inc.
/***************************************************************************************************************
*  Name: uart.c
*
*  Description: Initializes a UART port for use.  Also automatically sets up port for
*  use as stdout device.
*
*  uart_init - initializes the port, including setting the bps data rate
*  _mon_putc - overrides MPLAB weak function for directing stdout to the port
*
*  Calling Parameters:
*  
*  void uart_Init(	INT16 uartNum, 		// UART port , eg UART1A, UAR2A, etc
*					UINT32 bps,			// desired data rate in bits per second
*					UINT32 pbClk );		// PBCLK clock rate
*
*  Note: _mon_putc is an "invisible" function, not invoked by the user, but internally
*		 by stdout-related functions such as printf.  Many UART devices may be initialized
*		 using uart_Init, but the last port opened is saved and used by _mon_putc, thus
*		 making it the stdout port.
*
*  Returns:    None
*
*  Revision History:
*  Date    Who  Comments
*  ------  ---  -----------------------------------------------------------------------------------------
*  100525  RLP	Created.
*
***************************************************************************************************************/
#include "userLib.h"

static int uartDevNum;			// uart device # to use for stdin, stdout

void uart_init(INT16 uartNum, UINT32 bps, UINT32 pbClk)
{
	uartDevNum = uartNum;
	UARTConfigure(uartNum, UART_ENABLE_PINS_TX_RX_ONLY);
	UARTSetLineControl(uartNum, UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1);
	UARTSetDataRate(uartNum, pbClk, bps);
	UARTEnable(uartNum, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX));
}	

// override used by stdout routines to direct that traffic to port saved above in putcUartNum

// set stdout for output routines 

void _mon_putc(char c)
{
	while(!UARTTransmitterIsReady(uartDevNum))
		;

	UARTSendDataByte(uartDevNum, c);
}

// set stdin for input
int _mon_getc(int canblock)
{
	UINT8 chr;			// data character read

	while( !UARTReceivedDataIsAvailable(uartDevNum) )
	{
		if( !canblock )								// retn immediately; no block
			return(-1);								// no incoming data
	}

	chr = UARTGetDataByte(uartDevNum);				// get the char
	return( (int)chr );
}

// gets a line of data (until either \r or maxLen chars read
// returns chars actually read into buf

INT16 getLine( char *buf, INT16 maxLen )
{
	INT16	charsRead = 0;
	int		charData;			// input data 

	while(charsRead < maxLen)
	{
		charData = _mon_getc(0);
		if( charData >= 0 )					// char recvd
		{
			if( (char)charData == '\r' )
			{
				*buf = '\0';				// terminate buf
				break;						// done
			}
			*buf++ = (char)charData;		// store data
			++charsRead;					// bump count
		}
	}
	return(charsRead);
}
